/*
 * Copyright (C) 2015 Square, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.house365.arequest.convert;

import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.house365.arequest.ARequest;
import com.house365.arequest.BuildConfig;
import com.house365.arequest.exception.RequestFailException;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import okhttp3.ResponseBody;
import retrofit2.Converter;

/**
 * 这里对response进行拦截，请求错误的在这里处理
 * 请求错误时，通过异常的方式，流向onExError
 *
 * @param <T>
 */
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
    private final Gson gson;
    private final TypeAdapter<T> adapter;

    GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) {
        this.gson = gson;
        this.adapter = adapter;
    }

    @Override
    public T convert(ResponseBody value) throws IOException {
        JsonReader jsonReader = gson.newJsonReader(value.charStream());
        try {
            T result = adapter.read(jsonReader);
            if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
                throw new JsonIOException("JSON document was not fully consumed.");
            }
            /**在这里对已解析的json进行判断，目的是为了对json最外层进行判断，把请求错误的情况，交给onRxerror处理*/
            if (ARequest.getConvert() != null) {
                Type[] types = ARequest.getConvert().getClass().getGenericInterfaces();
                Type[] params = ((ParameterizedType) types[0]).getActualTypeArguments();
                Class reponseClass = (Class) params[0];
                if (reponseClass.isAssignableFrom(result.getClass())) {
                    if (!ARequest.getConvert().isSuccess(result)) {
                        throw new RequestFailException(ARequest.getConvert().getMsg(result));
                    }
                }
            }

            return result;
        } finally {
            value.close();
        }
    }
}
